package com.dylan.structure.queue;

import java.util.Arrays;
import java.util.Objects;
import java.util.Scanner;

/**
 * 循环队列
 *
 * @author zhangshaojian
 * @date 2022/7/12 10:51
 */
public class CycleQueue<T> implements MyQueue<T> {
    /**
     * 队列容器
     */
    private final Object[] container;
    /**
     * 容器最大存储数量
     */
    private final int maxSize;
    /**
     * 插入下标前一位
     */
    private int front;
    /**
     * 取出下标前一位
     */
    private int rear;
    /**
     * 容器中的数量
     */
    private int count;

    public CycleQueue(int maxSize) {
        this.maxSize = maxSize;
        container = new Object[maxSize];
        front = 0;
        rear = 0;
        count = 0;
    }

    public static void main(String[] args) {
        MyQueue<Integer> queue = new CycleQueue<>(5);
        Scanner scanner = new Scanner(System.in);
        while (true) {
            String operation = scanner.next();
            if (Objects.equals(operation, "a")) {
                int input = scanner.nextInt();
                System.out.println("添加元素 ：" + input);
                queue.put(input);
            } else if (Objects.equals(operation, "b")) {
                Integer take = queue.take();
                System.out.println("移除元素 ：" + take);
            } else if (Objects.equals(operation, "c")) {
                Integer take = queue.peek();
                System.out.println("当前元素 ：" + take);
            } else if (Objects.equals(operation, "d")) {
                System.out.println("共有元素 ：" + queue.count());
            } else if (Objects.equals(operation, "e")) {
                System.out.println("清除前共有元素 ：" + queue.count());
                queue.clear();
                System.out.println("清除后共有元素 ：" + queue.count());
            } else {
                queue.showAll();
            }
        }

    }

    @Override
    public boolean isEmpty() {
        return count == 0;
    }

    @Override
    public int count() {
        return count;
    }

    @Override
    public void put(T t) {
        if (isFull()) {
            System.out.println("container is full");
            return;
        }
        container[front++] = t;
        count++;
        if (front > maxSize - 1) {
            front = 0;
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public T take() {
        if (isEmpty()) {
            return null;
        }
        T result = (T) container[rear];
        container[rear++] = null;
        count--;
        if (rear > maxSize - 1) {
            rear = 0;
        }
        return result;
    }

    @Override
    @SuppressWarnings("unchecked")
    public T peek() {
        if (isEmpty()) {
            return null;
        }
        return (T) container[rear];
    }

    @Override
    public void clear() {
        Arrays.stream(container).forEach(each -> each = null);
        count = 0;
    }

    @Override
    public void showAll() {
        Arrays.stream(container).forEach(System.out::println);
    }

    @Override
    public boolean isFull() {
        return count == maxSize;
    }
}
